//
//  LRStatues.swift
//  LRWeibo
//
//  Created by 雷路荣 on 15/12/20.
//  Copyright © 2015年 leilurong. All rights reserved.
//
/**
*  微博属性模型数据
*/
import UIKit

import SDWebImage
// -[__NSCFNumber length]: unrecognized selector sent to instance 0xb0def2ca965ddb43, 看看是不是模型的属性类型出现错误
class LRStatues: NSObject {
    // MARK: - 1 属性
    /// 创建时间
    var created_at: String?
    
    /// 微博id
    var id: Int = 0
    
    /// 微博正文内容
    var text: String? {
        didSet{
            // 当KVC设置纯文本微博时,我们将表情名称替换成带表情图片的属性文本,只替换一次,以后都访问这个带表情图片的属性文本
            attrText = LREmoticon.stringToEmoticonText(text ?? "")
        }
    }
    /// 带表情图片的属性文本
    var attrText: NSAttributedString?
    /// 来源,只需要设置一次.以后都不会更改
    var source: String? {
        didSet {
            // 在KVC设置来源之后.我们自己再重新设置来源,再次赋值给source, 在didSet里面设置属性是不会调用属性监视器的
            source = source?.source()
        }
    }
    
    /*
    thumbnail_pic:	http://ww2.sinaimg.cn/thumbnail/b60d4a83jw1ezhqa7d0mqj20ku0rsn17.jpg
    
    bmiddle_pic:	http://ww2.sinaimg.cn/bmiddle/b60d4a83jw1ezhqa7d0mqj20ku0rsn17.jpg
    
    original_pic:	http://ww2.sinaimg.cn/large/b60d4a83jw1ezhqa7d0mqj20ku0rsn17.jpg
    */
    // 当我们获取到小图的地址后,获取大图只需要更换路径中的thumbnail单词
    /// 微博的配图 [String: AnyObject]数组,里面的元素是字典
    var pic_urls: [[String: AnyObject]]? {
        didSet{
            let count = pic_urls?.count ?? 0
            if count==0 {//没有图片
                return
            }
            // 创建数组保存转到的NSURL
            storePictureURLs = [NSURL]()
            // 创建大图图片的NSURL数组
            storeLargePictureURLS = [NSURL]()
            //遍历字典
            for dict in pic_urls! {
                //取出地址字符串
                let urlString = dict["thumbnail_pic"] as! String
                //转换为NSURL
                let url = NSURL(string: urlString)!
                //存储到数组中
                storePictureURLs?.append(url)
                // 大图的url,将小图的urlString替换thumbnail为large
                let largeUrlString = urlString.stringByReplacingOccurrencesOfString("thumbnail", withString: "large")
                //转换成url
                let largeURL = NSURL(string: largeUrlString)!
                //添加数组
                storeLargePictureURLS?.append(largeURL)
            }
        }
    }
    
    /// 自定义微博大图配图的NSURL数组
    var storeLargePictureURLS:[NSURL]?
    
    /// 如果是原创微博显示原创微博的大图图片,如果是转发微博显示被转发微博的大图图片
    var largePictureURLs: [NSURL]? {
        return retweeted_status == nil ? storeLargePictureURLS : retweeted_status?.storeLargePictureURLS
    }

    /// 自定义微博配图的NSURL数组.
    var storePictureURLs: [NSURL]?
    
    /// 如果是原创微博显示原创微博的图片,如果是转发微博显示转发微博的图片
    var pictureURLs: [NSURL]? {
        // 如果是原创微博显示原创微博的图片: storePictureURLs
        // 如果是转发微博显示转发微博里的的图片: retweeted_status?.storePictureURLs
        return retweeted_status == nil ? storePictureURLs : retweeted_status?.storePictureURLs
    }
    /// 转发数
    var reposts_count: Int = 0
    
    /// 评论数
    var comments_count: Int = 0
    
    /// 表态数(赞)
    var attitudes_count: Int = 0
    
    /// 用户模型
    var user: LRUser?
    
    /// 被转发微博模型属性,只有转发的微博模型才有,原创的微博模型是没有的
    var retweeted_status: LRStatues?
    
    /// 缓存行高, rowHeight == nil 说明没有缓存过行高
    var rowHeight: CGFloat?
    
    /// 自定义cell的缓存重用标识,根据不同模型返回不同的缓存标识
    func cellID() -> String {
        // 判断是原创的模型,还是转发的模型.根据retweeted_status来判断
        // 如果retweeted_status有值,是一个转发微博
        // 如果retweeted_status没有值,是一个原创微博
        return retweeted_status == nil ? LRStatusCellReuseIdentifier.StatuesOriginalCell.rawValue : LRStatusCellReuseIdentifier.StatuesTransmitCell.rawValue
    
    }
    //MARK - 2.字典转模型
    init(dict:[String: AnyObject]) {
        super.init()
        setValuesForKeysWithDictionary(dict)
    }
    //MARK - 3.字典的key在模型中找不到对应的属性,需要实现 forUndefinedKey
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
    //MARK - 4 setValuesForKeysWithDictionary传入的key有多少个就会调用用多少次,并且传入相应的key和value
    override func setValue(value: AnyObject?, forKey key: String) {
        //print("key:\(key)")
        // 判断如果是user这个key,我们自己来字典转模型,不需要kvc
        if key == "user" {
            //我们自己来字典转模型
            if let dict = value as? [String: AnyObject] {
            //字典转模型
            self.user = LRUser(dict: dict)
            }
            // 一定要记得return,不然会调用父类的setValue,会被覆盖
            return
        }
        // 判断key如果是retweeted_status我们将字典转成模型
        if key == "retweeted_status" {
            // 我们自己字典转模型
            if let dict = value as? [String: AnyObject] {
                // 字典转模型
                retweeted_status = LRStatues(dict: dict)
            }
            return// 一定要记得return,不然会调用父类的setValue,会被覆盖
        }
        super.setValue(value, forKey: key)
    }
    //MARK -5.实现description属性
//    override var description: String {
//        let propertyArr = ["created_at", "id", "text", "source", "pic_urls", "reposts_count", "comments_count", "attitudes_count", "user"]
//        // 通过一个数组来生成一个字典,数组中的元素,会成为字典的key,key所对应的value，会从模型中来找对应的属性值
//        let dict = dictionaryWithValuesForKeys(propertyArr)
//        // \n 换行, \t table键
//        return "\n\t微博模型LRStatues:\(dict)"
//    }
    //MARK - 6 加载微博数据  [LRStatues]是存储LRStatues的数组
    class func loadStatues(since_id: Int, max_id: Int, finished:(statues:[LRStatues]? ,error: NSError?)->()) {
        
        // 从DAL加载数据,DAL去哪里加载的数据我们不关心,模型需要做的是拿到数据,将数据字典转模型
        LRStatusDAL.sharedInstance.loadStatus(since_id, max_id: max_id) { (statuses, error) -> () in
            if error != nil {
                finished(statues: nil, error: error)
                return
            }
            // 加载数据没有出错,来字典转模型
            if let array = statuses {
                // 遍历数组,获取里面的字典来转模型
                var statusesModel = [LRStatues]()
                for dict in array {
                    statusesModel.append(LRStatues(dict: dict))
                }
                //缓存
                cachedWedImage(statusesModel, finished: finished)
            }else{
                finished(statues: nil, error: nil)
            }
            
        }
/*
        //直接调用网络工具类的方法来加载微博数据
        LRNetworkTool.sharedNetworkTool.loadStatusData (since_id, max_id: max_id) { (result, error) -> () in
            //如果有错或者没有数据，回调返回错误
            if result == nil || error != nil {
                finished(statues: nil, error: error)
                return
            }
            // 没有错误,有数据
            // 6.2 字典转模型,判断字典是否有statuses,将statuses的值转成数组,数组里面存放的是字典
            if let array = result?["statuses"] as? [[String: AnyObject]] {
                // 6.3 创建一个空数组,来存放转好的模型
                var statuesArr = [LRStatues]()
                // 6.4 遍历数组
                for dict in array {
                    //6.5 字典转模型
                    let status = LRStatues(dict: dict)
                    // 6.6 将转好的模型添加到模型数组里面
                    statuesArr.append(status)
                }
                //所有的模型都转换完成,告诉调用的人有微博模型数据了
                //finished(statues: statuesArr, error: nil)
                cachedWedImage(statuesArr, finished: finished)
            }else{
                finished(statues: nil, error: nil)
            }
        }
*/
    }
    
    // 单张图片显示图片原本的大小
    // 需要知道图片的大小,因为新浪的api没有返回图片大小
    // 先将图片下载到本地(SDWebImage).然后就可以获取到图片的大小
    class func cachedWedImage(statuses:[LRStatues], finished:(statues:[LRStatues]? ,error: NSError?)->()) {
        // 1. 缓存图片的大小
        var length = 0.0
        // 2. 创建任务组
        let group = dispatch_group_create()
        // 3. 遍历所有模型
        for statue in statuses {
            guard let urls = statue.pictureURLs else {
                // 没有图片要缓存,跳到下一个模型
                continue
            }
            // 5. 有图片,遍历缓存所有图片
            // 只有一张图片的时候需要提前知道大小.多张图片的时候可以在显示的时候在下载,可以减少图片的缓存时间
            if urls.count == 1 {
                let url = urls[0]
                //  6. SDWebImageManager缓存图片.是一个异步的任务
                // 6.1 在异步任务之前进入组
                dispatch_group_enter(group)
                // 6.2 执行异步下载图片
                SDWebImageManager.sharedManager().downloadImageWithURL(url, options: SDWebImageOptions(rawValue: 0), progress: nil, completed: { (image, error, _, _, _) -> Void in
                    // 6.3 只要异步任务完成就离开组
                    dispatch_group_leave(group)
                    if error != nil {
                        print("缓存图片失败: \(url)")
                        return
                    }
                    //print("缓存图片成功: \(url)")
                    let data = UIImagePNGRepresentation(image)
                    length += Double((data?.length)!)
                })
            }
        }
        // 7. 在所有的异步任务完成后再来执行]
        dispatch_group_notify(group, dispatch_get_main_queue()) { () -> Void in
            print("所有图片下载完成, 大小:\(length / 1024 / 1024) M")
            // 8. 通知别人,获取到所有的微博,调用闭包
            finished(statues: statuses, error: nil)
        }
    
    }
    
    
    
    
    
    
    
    
   
}



























